import 'package:flutter/material.dart';
import 'package:flutter_drawer_demo/layers/index.dart';

/// 单一 GestureDetector，拦截所有手势，选中并转发给当前 Layer
class LayerCanvas extends StatefulWidget {
  final List<Layer> layers;
  final void Function(String id, dynamic metric)? onLayerMetricChanged;
  const LayerCanvas(
      {super.key, required this.layers, this.onLayerMetricChanged});

  @override
  State<LayerCanvas> createState() => _LayerCanvasState();
}

class _LayerCanvasState extends State<LayerCanvas> {
  Layer? selectedLayer;

  void _handleTap(Offset pos) {
    for (final layer in widget.layers.reversed) {
      if (layer.hitTest(pos)) {
        selectedLayer = layer;
        for (var l in widget.layers) {
          l.selected = l == layer;
        }
        return;
      }
    }
    selectedLayer = null;
    for (var l in widget.layers) {
      l.selected = false;
    }
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (_, bc) {
      final Size boundary = Size(bc.maxWidth, bc.maxHeight);
      return GestureDetector(
        behavior: HitTestBehavior.opaque,
        onTapDown: (dt) => setState(() => _handleTap(dt.localPosition)),
        onPanStart: (dt) => setState(() {
          selectedLayer?.onPanStart(dt.localPosition, boundary);
        }),
        onPanUpdate: (dt) => setState(() {
          selectedLayer?.onPanUpdate(dt.localPosition, boundary);
        }),
        onPanEnd: (dt) => setState(() {
          selectedLayer?.onPanEnd(boundary);
          if (selectedLayer is LineLayer || selectedLayer is EllipseLayer) {
            dynamic endValue = selectedLayer?.getMetric();
            widget.onLayerMetricChanged
                ?.call(selectedLayer?.id ?? 'unknown', endValue ?? 0.0);
          }
        }),
        child: CustomPaint(
          size: boundary,
          painter: _CanvasPainter(widget.layers),
        ),
      );
    });
  }
}

class _CanvasPainter extends CustomPainter {
  final List<Layer> layers;
  _CanvasPainter(this.layers);

  @override
  void paint(Canvas canvas, Size size) {
    // 背景
    canvas.drawRect(Offset.zero & size, Paint()..color = Colors.grey[900]!);
    for (final layer in layers) {
      layer.paint(canvas, size);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter old) => true;
}
